package com.github.llyb120.driver.qiuya;

import com.github.llyb120.json.Json;
import com.github.llyb120.json.Obj;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class MyWebSocketClient extends WebSocketClient {

    private WebSocket webSocket;
    private AtomicInteger countDown = new AtomicInteger(0);
    private ExecutorService reconnectService = Executors.newFixedThreadPool(1);
    private int index;

    public MyWebSocketClient(WebSocket webSocket, URI serverUri, int index) {
        super(serverUri);
        this.webSocket = webSocket;
        this.index = index;
        webSocket.executor.execute(() -> {
            if(index > 0){
                try {
                    Thread.sleep(index * 500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.connect();
        });
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        try {
            webSocket.openPool.put(this);
            countDown.set(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onMessage(String s) {
        int i0 = s.indexOf(' ');
        if(i0 == -1){
            return;
        }
        if(!s.substring(0, i0).equals("ack")){
            return;
        }
        int i1 = s.indexOf(' ', i0 + 1);
        if(i1 == -1){
            return;
        }
        String ack = s.substring(i0 + 1, i1);
        String data = s.substring(i1 + 1);

        Message source = webSocket.acks.get(ack);
        if (source == null) {
            return;
        }
        Obj obj = Json.parse(data);
        if (obj == null) {
            return;
        }
        source.result = obj;
        source.cd.countDown();
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        this._reconnect();
    }

    @Override
    public void onError(Exception e) {
        this._reconnect();
    }

    public void _reconnect(){
        if(this.isOpen()){
            return;
        }
        this.webSocket.openPool.remove(this);
        reconnectService.execute(() -> {
            try {
                this.reconnectBlocking();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(countDown.get() == 10){
                countDown.set(9);
            }
        });
    }
}
